﻿using Futaba.SBus.Extensions;
using Futaba.SBus.Telemetry;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace Futaba.SBus.SampleApplication.TelemetryLiveView
{
	class SlotWithHistory : NotifyPropertyChangedBase, ISlot
	{

		readonly ISlot _innerSlot;

		public SlotWithHistory(ISlot innerSlot)
		{
			innerSlot.EnsureNotNull("innerSlot");
			_innerSlot = innerSlot;
			SlotValues = new ObservableCollection<SlotValue>();
			var npc = innerSlot as System.ComponentModel.INotifyPropertyChanged;
			if (npc != null)
				npc.PropertyChanged += OnInnerPropertyChanged;

			SortOrder = Slot.GetSlotNumber(innerSlot.SlotId);
			Visibility = System.Windows.Visibility.Visible;
		}

		public ObservableCollection<SlotValue> SlotValues { get; private set; }

		private int _internalSortOrder;
		public int SortOrder
		{
			get { return _internalSortOrder; }
			set
			{
				if (Equals(_internalSortOrder, value))
					return;
				_internalSortOrder = value;
				RaisePropertyChanged(); //RaisePropertyChanged("SortOrder");
			}
		}

		private Visibility _internalVisibility;
		public Visibility Visibility
		{
			get { return _internalVisibility; }
			set
			{
				if (Equals(_internalVisibility, value))
					return;
				_internalVisibility = value;
				RaisePropertyChanged(); //RaisePropertyChanged("Visibility");
			}
		}

		private byte _internalSequence;
		public byte Sequence
		{
			get { return _internalSequence; }
			set
			{
				if (Equals(_internalSequence, value))
					return;
				_internalSequence = value;
				RaisePropertyChanged(); //RaisePropertyChanged("Sequence");
			}
		}

		private void OnInnerPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
		{
			if (e.PropertyName == "CurrentValue")
				LogValue(_innerSlot.CurrentValue, _innerSlot.ReceivedUtc);
			RaisePropertyChanged(e.PropertyName);
		}

		private void LogValue(double? currentValue, DateTime receivedUtc)
		{
			SlotValues.Add(new SlotValue(currentValue, receivedUtc));
		}

		#region Decoration

		public Telemetry.Configuration.Sensor Sensor
		{
			get
			{
				return _innerSlot.Sensor;
			}
			set
			{
				_innerSlot.Sensor = value;
			}
		}

		public Telemetry.Configuration.SensorType SensorType
		{
			get
			{
				return _innerSlot.SensorType;
			}
			set
			{
				_innerSlot.SensorType = value;
			}
		}

		public SlotIdType SlotId
		{
			get
			{
				return _innerSlot.SlotId;
			}
			set
			{
				_innerSlot.SlotId = value;
			}
		}

		public double ValueMultiplyer
		{
			get
			{
				return _innerSlot.ValueMultiplyer;
			}
			set
			{
				_innerSlot.ValueMultiplyer = value;
			}
		}

		public string DisplayName
		{
			get
			{
				return _innerSlot.DisplayName;
			}
			set
			{
				_innerSlot.DisplayName = value;
			}
		}

		public string ParameterName
		{
			get
			{
				return _innerSlot.ParameterName;
			}
			set
			{
				_innerSlot.ParameterName = value;
			}
		}

		public Telemetry.Configuration.SensorParameter Parameter
		{
			get
			{
				return _innerSlot.Parameter;
			}
			set
			{
				_innerSlot.Parameter = value;
			}
		}

		public double? CurrentValue
		{
			get
			{
				return _innerSlot.CurrentValue;
			}
			set
			{
				_innerSlot.CurrentValue = value;
			}
		}

		public DateTime ReceivedUtc
		{
			get
			{
				return _innerSlot.ReceivedUtc;
			}
			set
			{
				_innerSlot.ReceivedUtc = value;
			}
		}

		public SlotValueParserContext ParseContext
		{
			get { return _innerSlot.ParseContext; }
		}

		#endregion

	}
}
